﻿namespace ChessToys
{
    using System;
    using System.Collections.Generic;

    public class KingMoveGenerator : AbstractPieceMoveGenerator<King>
    {
        protected override ISet<Move> GenerateForSpecificPiece(Board board, Position start, King piece)
        {
            // prepare moves
            ISet<Move> moves = new HashSet<Move>();
            // up
            moves.UnionWith(Crawl(board, start, new Position(0, -1), new Position(-1, start.Y - 2)));
            // down
            moves.UnionWith(Crawl(board, start, new Position(0, 1), new Position(8, start.Y + 2)));
            // right
            moves.UnionWith(Crawl(board, start, new Position(1, 0), new Position(start.X + 2, 8)));
            // left
            moves.UnionWith(Crawl(board, start, new Position(-1, 0), new Position(start.X - 2, -1)));
            // up right
            moves.UnionWith(Crawl(board, start, new Position(1, -1), new Position(start.X + 2, start.Y - 2)));
            // up left
            moves.UnionWith(Crawl(board, start, new Position(-1, -1), new Position(start.X - 2, start.Y - 2)));
            // down right
            moves.UnionWith(Crawl(board, start, new Position(1, 1), new Position(start.X + 2, start.Y + 2)));
            // down left
            moves.UnionWith(Crawl(board, start, new Position(-1, 1), new Position(start.X - 2, start.Y + 2)));
            // rochade
            {
                // white rochades
                if (PieceUtils.Is(piece, typeof(King), Color.White))
                {
                    // white king-side rochade
                    if (board.Rochade.WhiteKingSide &&
                        board[new Position(5,7)] == null && board[new Position(6,7)] ==  null)
                    {
                        moves.Add(new RochadeMove(new Move(start, new Position(6,7)), new Move(new Position(7,7), new Position(5,7))));
                    }
                    // white queen-side rochade
                    if (board.Rochade.WhiteQueenSide &&
                        board[new Position(3, 7)] == null && board[new Position(2, 7)] == null && board[new Position(1, 7)] == null)
                    {
                        moves.Add(new RochadeMove(new Move(start, new Position(1, 7)), new Move(new Position(0, 7), new Position(2, 7))));
                    }
                }
                // black rochades
                if (PieceUtils.Is(piece, typeof(King), Color.Black))
                {
                    // black king-side rochade
                    if (board.Rochade.BlackKingSide &&
                        board[new Position(5, 0)] == null && board[new Position(6, 0)] == null)
                    {
                        moves.Add(new RochadeMove(new Move(start, new Position(6, 0)), new Move(new Position(7, 0), new Position(5, 0))));
                    }
                    // black queen-side rochade
                    if (board.Rochade.BlackQueenSide &&
                        board[new Position(3, 0)] == null && board[new Position(2, 0)] == null && board[new Position(1, 0)] == null)
                    {
                        moves.Add(new RochadeMove(new Move(start, new Position(1, 0)), new Move(new Position(0, 0), new Position(2, 0))));
                    }
                }
            }
            // return moves
            return moves;
        }
    }
}
